﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Snowdreamist.Text.UBB
{
    internal class ColorFactory : PrefixUBBElementFactory
    {
        public ColorFactory() : base(ElementPrefix) { }

        public override bool IsLabel(string content, out IUBBElementFactory factory)
        {
            if (!base.IsLabel(content, out factory))
                return false;
            // try to match regex
            var r = ElementTextRegex.IsMatch(content) || ElementHexRegex.IsMatch(content);
            if (r)
                factory = this;
            return r;
        }

        public override UBBElement Create(UBBContent ubbContent)
        {
            var text = ubbContent.Text;

            // try match text
            var matchResult = ElementTextRegex.Match(text);
            if (matchResult.Success)
            {
                KnownColor knownColor;
                if (Enum.TryParse<KnownColor>(matchResult.Groups[1].Value, true, out knownColor))
                    return new ColorElement(Color.FromKnownColor(knownColor));
            }

            // try match hex
            matchResult = ElementHexRegex.Match(text);
            if (matchResult.Success)
            {
                // a hex number
                Int32 num = Convert.ToInt32(matchResult.Groups[1].Value, 16);
                return new ColorElement(Color.FromArgb(num));
            }
            // return default
            return new ColorElement();
        }

        #region private

        private readonly static string ElementPrefix = "color";

        private readonly static Regex ElementTextRegex = new Regex(@"color=([a-zA-Z]+)", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled);

        private readonly static Regex ElementHexRegex = new Regex(@"color=\#([0-9A-F]{1,8})", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled);

        #endregion private
    }

    public class ColorElement : UBBElement
    {
        public const string Label = "color";

        public ColorElement() : this(Color.Black) { }

        public ColorElement(Color color)
            : base(Label)
        {
            this.Color = color;
        }

        public Color Color { get; private set; }

        public override string SerializeToUBBCode()
        {
            if (this.Color.IsNamedColor)
            {
                return Label + "=" + this.Color.Name;
            }
            else
            {
                return Label + "=#" + Convert.ToString(this.Color.ToArgb(), 16);
            }
        }

        public override object Clone()
        {
            return new ColorElement(this.Color);
        }
    }
}